#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <unistd.h>
#include "ring_queue.h"
#include "golfdds_shm.h"

const char *get_exe_path() {
  static char path[1024]; // 存放路径字符串的数组

  ssize_t len = readlink("/proc/self/exe", path, sizeof(path) - 1);
  if (len != -1) {
    path[len] = '\0';

    printf("当前可执行文件路径为：%s\n", path);
    return path;
  } else {
    perror("无法读取链接");
    return NULL;
  }
}

Ring_Queue *create_or_attach_shm(const char *path, int shm_index, size_t size, int nmemb, int *pshmid) {
  // 使用ftok函数获取键值
  key_t mykey;
  if ((mykey = ftok(path, shm_index)) == -1) {
    printf("create_or_attach_shm:fail to ftok:%s,%d\n", path, shm_index);
    perror("fail to ftok");
    return NULL;
  } else {
    // 通过shmget函数创建或者打开一个共享内存，返回一个共享内存的标识符
    int shmid;
    if ((shmid = shmget(mykey, nmemb * (sizeof(TAG) + size) + sizeof(Ring_Queue), IPC_CREAT | 0666)) == -1) {
      perror("fail to shmget");
      return NULL;
    }
    Ring_Queue *ring;
    if ((ring = (Ring_Queue *)shmat(shmid, NULL, 0)) == (void *)-1) {
      perror("fail to shmat");
      return NULL;
    }
    ring = Create_Ring_Queue_SHM(nmemb, size, ring);
    *pshmid = shmid;
    return ring;
  }
}
Ring_Queue *attach_shm(const char *path, int shm_index, int *pshmid) {
  // 使用ftok函数获取键值
  key_t mykey;
  if ((mykey = ftok(path, shm_index)) == -1) {
    printf("attach_shm,fail to ftok:%s,%d\n", path, shm_index);
    perror("fail to ftok");
    return NULL;
  } else {
    // 通过shmget函数创建或者打开一个共享内存，返回一个共享内存的标识符
    int shmid;
    if ((shmid = shmget(mykey, 0, 0666)) == -1) {
      printf("fail to shmget:%s,%d", path, shm_index);
      perror("fail to shmget");
      return NULL;
    }
    Ring_Queue *ring;
    if ((ring = (Ring_Queue *)shmat(shmid, NULL, 0)) == (void *)-1) {
      perror("fail to shmat");
      return NULL;
    }
    *pshmid = shmid;
    return ring;
  }
}
int detach_shm(Ring_Queue *ring) {
  // 解除共享内存映射
  if (shmdt(ring) == -1) {
    perror("fail to shmdt");
    return -1;
  }
  return 0;
}

int delete_shm(const char *path, int shm_index) {
  // 使用ftok函数获取键值
  key_t mykey;
  if ((mykey = ftok(path, shm_index)) == -1) {
    printf("delete_shm:fail to ftok:%s,%d\n", path, shm_index);
    perror("fail to ftok");
    return -1;
  } else {
    // 通过shmget函数创建或者打开一个共享内存，返回一个共享内存的标识符
    int shmid;
    if ((shmid = shmget(mykey, 0, 0666)) == -1) {
      perror("fail to shmget");
      return -1;
    }
    // 通过shmctl函数删除共享内存
    if (shmctl(shmid, IPC_RMID, NULL) == -1) {
      perror("fail to shmctl");
      return -1;
    }
    return 0;
  }
}